
#ifndef TIPODATO_H_
#define TIPODATO_H_

/**********************************************************************
 *	tipo_dato.h
 * 
 *  Descripcion: Clase que representa un tipo generico de un campo.
 *  A un objeto de esta clase se le puede ingresar y extraer un valor,
 *  compararlo con otro, etc.
 * *******************************************************************/

#include "excep_error_tipos.h"
#include <iostream>

using namespace std;

enum CodTipo {INT, STRING, STRUCT, COLECCION};

class TipoDato {
	
	protected:
		
		bool obligatorio;
		
	public:
		
		/*
		 * Destructor virtual:
		 */ 
		virtual ~TipoDato(){}
		
		/*
		 * Constructor
		 */ 
		TipoDato(bool es_obligatorio);		
		
		/*
		 * Constructor por defecto que pone true a obligatorio y 
		 * false a uno_a_muchos
		 */ 
		TipoDato();
		
		//Metodos:
		
		/*
		 * Devuelve si el tipo de dato es oblicatorio
		 */ 
		bool es_obligatorio() const;
		
		/*
		 * Esta cargado: Devuelve true si el dato esta cargado,
		 * false en caso contrario.
		 */
		virtual bool esta_cargado() const = 0;
		
		/*
		 * Mismo tipo: Devuelve true si los 2 datos son del mismo tipo,
		 * false en caso contrario.
		 */
		 virtual bool mismo_tipo(const TipoDato& dato) const;
		 
		/*
		 * Op de insercion: Permite asignar un valor al objeto del tipodato.
		 * Si los tipos son incompatibles, arroja una ExcepErrorTipos.
		 */ 
		virtual TipoDato& operator= (const TipoDato& dato) throw (ExcepErrorTipos) = 0;
		
		/*
		 * Op de igualacion: Devuelve true si los valores de los datos son
		 * iguales, false en caso contrario.
		 * Si los tipos son incompatibles, arroja una ExcepErrorTipos.
		 */
		virtual bool operator==(const TipoDato& dato) const throw (ExcepErrorTipos) = 0;
		
		/*
		 * Op <: Devuelve true si el valor del dato actual es menor al del
		 * pasado por param, false en caso contrario.
		 * Si los tipos son incompatibles, arroja una ExcepErrorTipos.
		 */
		virtual bool operator< (const TipoDato& dato) const throw (ExcepErrorTipos) = 0;
		
		/*
		 * Op <=: Devuelve true si el valor del dato actual es menor o igual al del
		 * pasado por param, false en caso contrario.
		 * Si los tipos son incompatibles, arroja una ExcepErrorTipos.
		 */
		bool operator<= (const TipoDato& dato) throw (ExcepErrorTipos);
		
		/*
		 * Get Codigo Tipo: Devuelve el codigo del tipo de dato en cuestion.
		 */
		virtual CodTipo get_codigo_tipo() const = 0;
		
		/*
		 * Clonar: Devuelve la referencia a un nuevo dato con el mismo 
		 * contenido que el actual.
		 * El nuevo objeto es creado en heap y debe ser liberado.
		 */
		virtual TipoDato* clonar() const = 0;
		
		 /*
		 * ToStream: Dado un stream de salida, pasa la representacion del dato
		 * al mismo.
		 */
		virtual ostream& toStream(ostream& out) const = 0;
		
		/*
	 	* get_tamanio: Devuelve la cantidad de campos del tipo.
	 	*/
		virtual unsigned int get_tamanio() const = 0;

		/*
	     * Operador <<: Imprime el tipodato en el stream de salida pasado por param.
	     */
	    friend ostream& operator<< (ostream& out, const TipoDato& tdato){
			return tdato.toStream(out);
		}
		
		/*
		 * Crea una cadena que contiene el dato serializado. La devuelve
		 * en retorno y asigna el tamano de la misma en tam
		 */ 
		virtual void serializar(char ** retorno, unsigned int &tam) = 0;
		
		/*
		 * Obtiene un tipo de dato a partir de los datos serializados.
		 * Debe recibir el tamano de tamano de la cadena de serializados.
		 * Devuelve true si pudo realizar bien la operacion, false en
		 * caso contrario
		 */ 
		virtual bool deserializar(char * serializados, unsigned int tam) = 0;

		/*
		 * Obtiene el tamanio en bites que ocupa el elemento serializado.
		 * Para esto, llama de forma polimorfica al serializar.
		 */
		 virtual unsigned int get_tamanio_serializado(); 

};

#endif

